package guida.ccf.gzuexaminesystem.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import guida.ccf.gzuexaminesystem.common.Bucket;
import guida.ccf.gzuexaminesystem.common.HttpStatus;
import guida.ccf.gzuexaminesystem.common.HttpStatusDescriptionsImpl;
import guida.ccf.gzuexaminesystem.common.ResponseResult;
import guida.ccf.gzuexaminesystem.dto.StudentSaveFileDto;
import guida.ccf.gzuexaminesystem.dto.TeamMateDto;
import guida.ccf.gzuexaminesystem.entity.Instructor;
import guida.ccf.gzuexaminesystem.entity.StudentAward;
import guida.ccf.gzuexaminesystem.entity.minio.DeleteFileDto;
import guida.ccf.gzuexaminesystem.entity.minio.SaveFileDto;
import guida.ccf.gzuexaminesystem.mapper.StudentAwardMapper;
import guida.ccf.gzuexaminesystem.service.InstructorService;
import guida.ccf.gzuexaminesystem.service.StudentAwardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import guida.ccf.gzuexaminesystem.utils.MinioUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ccf
 * @since 2023-11-03
 */
@Service
@Transactional
public class StudentAwardServiceImpl extends ServiceImpl<StudentAwardMapper, StudentAward> implements StudentAwardService {

    @Autowired
    private InstructorService instructorService;

    @Autowired
    private MinioUtil minioUtil;

    @Autowired
    private HttpStatusDescriptionsImpl descriptions;


    /**
     * 项目材料上传文件
     * @param files 文件数组
     * @param md5s md5 数组
     * @return 返回结果
     */
    @Override
    public ResponseResult<?> saveFile(StudentSaveFileDto fileDto, MultipartFile[] files, String[] md5s) {

        // 标识是团队赛还是个人赛
        String isTeam = fileDto.getType().equals("team") ? "1" : "0";

        List<SaveFileDto> list = new ArrayList<>();
        String folder = fileDto.getFolder();

        for (int i = 0; i < files.length; ++i) {
            // 构造数组
            SaveFileDto saveFileDto = new SaveFileDto();

            saveFileDto.setBucket(Bucket.STUDENT_BUCKET);
            saveFileDto.setFile(files[i]);
            saveFileDto.setFolder(folder);
            saveFileDto.setMd5(md5s[i]);

            list.add(saveFileDto);
        }

        boolean flag = minioUtil.saveFileAll(list);

        if(flag){
            /*
             * 文件上传成功，保存到数据库中
             */
            StudentAward studentAward = new StudentAward();
            BeanUtils.copyProperties(fileDto, studentAward);
            if (isTeam.equals("1")) {
                // 团体赛, 那么上传的人是队长
                studentAward.setTeamLeader("1");
                studentAward.setIsTeam("1");
            }
            boolean save = save(studentAward);

            // 获取指导老师数组
            List<String> teachers = fileDto.getTeachers();

            // 插入 instructor 表.
            List<Instructor> instructorList = new ArrayList<>();
            for (String teacher : teachers) {
                Instructor instructor = new Instructor();
                BeanUtils.copyProperties(fileDto, instructor);

                // 设置比赛类型: 团体 或 个人
                instructor.setIsTeam(isTeam);
                instructor.setId(null);
                instructor.setTeacherName(teacher);

                instructorList.add(instructor);
            }
            if (instructorList.size() > 0) {
                save = instructorService.saveBatch(instructorList);
            }

            if (isTeam.equals("1")) {
                // 团体赛, 为队员插入记录
                List<TeamMateDto> teamMates = fileDto.getTeamMates();
                List<StudentAward> awards = new ArrayList<>();
                for (TeamMateDto mate : teamMates) {
                    StudentAward award = new StudentAward();
                    BeanUtils.copyProperties(fileDto, award);
                    studentAward.setIsTeam("1");

                    awards.add(award);
                }

                save = saveBatch(awards);
            }

            if (save) {
                return ResponseResult.success(descriptions.getDescription(HttpStatus.OK));
            } else {
                /*
                 * DeleteFileDto:
                 *     private String bucket;
                 *     private String folder;
                 *     private String fileName;
                 */
                List<DeleteFileDto> deleteFileDtos = new ArrayList<>();

                for (SaveFileDto saveFileDto : list) {
                    DeleteFileDto deleteFileDto = new DeleteFileDto();
                    deleteFileDto.setFileName(saveFileDto.getFile().getName());
                    deleteFileDto.setBucket(saveFileDto.getBucket());
                    deleteFileDto.setFolder(saveFileDto.getFolder());

                    deleteFileDtos.add(deleteFileDto);
                }
                deleteFileAll(deleteFileDtos);
                throw new RuntimeException("上传失败!");
            }
        } else {
            throw new RuntimeException("上传失败!");
        }
    }

    /**
     *
     * @param studentBucket 桶
     * @param folder 文件路径
     * @param fileName 文件名
     * @param md5 文件md5值
     */
    @Override
    public String getFile(String studentBucket, String folder, String fileName, String md5, HttpServletResponse response) {

        boolean flag = minioUtil.getFile(studentBucket,folder,fileName,md5,response);

        if(flag){
            return "正在下载文件";
        }else{
            return "文件下载失败";
        }
    }

    /**
     * 上传失败时,删除文件
     */
    public void deleteFileAll(List<DeleteFileDto> list) {
       minioUtil.deleteFileAll(list);
//
//        if(flag){
//            // todo 执行数据库
//            return ResponseResult.success(descriptions.getDescription(HttpStatus.OK));
//        }else{
//            return ResponseResult.fail(descriptions.getDescription(HttpStatus.FAILED));
//        }
    }

    /**
     * 学生获取自己的审核中的获奖记录
     * @param studentId 学号
     */
    @Override
    public ResponseResult<?> getUnderReviewAward(String studentId) {

        LambdaUpdateWrapper<StudentAward> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StudentAward::getStudentId, studentId)
                .eq(StudentAward::getStatus, "2");

        List<StudentAward> result = list(lambdaUpdateWrapper);

        return ResponseResult.success(result);
    }

    /**
     * 学生获取自己的审核成功的获奖记录
     * @param studentId 学号
     */
    @Override
    public ResponseResult<?> getReviewAwardPassed(String studentId) {
        LambdaUpdateWrapper<StudentAward> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StudentAward::getStudentId, studentId)
                .eq(StudentAward::getStatus, "1");

        List<StudentAward> result = list(lambdaUpdateWrapper);

        return ResponseResult.success(result);
    }

    @Override
    public ResponseResult<?> getReviewAwardFailed(String studentId) {
        LambdaUpdateWrapper<StudentAward> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(StudentAward::getStudentId, studentId)
                .eq(StudentAward::getStatus, "0");

        List<StudentAward> result = list(lambdaUpdateWrapper);

        return ResponseResult.success(result);
    }
}
